package com.zbkj.service.service.order.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.collect.Maps;
import com.zbkj.dal.base.constants.OrderConstants;
import com.zbkj.dal.base.enums.ExpressOrderType;
import com.zbkj.dal.base.enums.OrderStatusEnums;
import com.zbkj.dal.base.enums.OrderType;
import com.zbkj.dal.base.enums.merchant.MerOrderApptType;
import com.zbkj.dal.base.enums.show.EnumShowVO;
import com.zbkj.dal.base.page.CommonPage;
import com.zbkj.dal.common.exception.CrmebException;
import com.zbkj.dal.common.utils.SecurityUtil;
import com.zbkj.dal.dao.OrderDao;
import com.zbkj.dal.entity.admin.SystemAdmin;
import com.zbkj.dal.entity.merchant.MerchantOrderAppointment;
import com.zbkj.dal.entity.order.*;
import com.zbkj.dal.entity.user.User;
import com.zbkj.dal.pojo.request.OrderSendRequest;
import com.zbkj.dal.pojo.request.order.merchant.AdminMerchantRentOrderQueryRequest;
import com.zbkj.dal.pojo.request.order.merchant.AdminMerchantRentOrderVerifyRequest;
import com.zbkj.dal.pojo.response.OrderInfoFrontDataResponse;
import com.zbkj.dal.pojo.response.UserInfoResponse;
import com.zbkj.dal.pojo.response.order.merchant.MerchantOrderDetailNewResponse;
import com.zbkj.dal.pojo.response.order.merchant.MerchantOrderPageNewResponse;
import com.zbkj.dal.pojo.vo.LogisticsResultVo;
import com.zbkj.service.model.dto.order.OrderInvoiceDTO;
import com.zbkj.service.service.*;
import com.zbkj.service.service.merchant.MerchantOrderAppointmentService;
import com.zbkj.service.service.order.merchant.AdminMerchantRentOrderV2Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wangzhengyan
 * @date 2024/4/9 8:34 PM
 */
@Service
@Slf4j
public class AdminMerchantRentOrderV2ServiceImpl extends ServiceImpl<OrderDao, Order> implements AdminMerchantRentOrderV2Service {

    @Resource
    private OrderDao dao;
    @Resource
    private UserService userService;
    @Resource
    private MerchantOrderService merchantOrderService;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderService orderService;
    @Resource
    private MerchantOrderAppointmentService merchantOrderAppointmentService;
    @Resource
    private OrderInvoiceService orderInvoiceService;
    @Resource
    private OrderAddressService orderAddressService;
    @Resource
    private SmsService smsService;

    @Override
    public List<EnumShowVO<Integer>> getOrderStatusList() {
        List<EnumShowVO<Integer>> statusList = new ArrayList<>();
        OrderStatusEnums.rentStatus().forEach(x-> {
            EnumShowVO<Integer> vo = new EnumShowVO<>();
            vo.setCode(x.getCode());
            vo.setDesc(x.getDesc());
            statusList.add(vo);
        });
        return statusList;
    }

    @Override
    public PageInfo<MerchantOrderPageNewResponse> getAdminMerchantOrderList(AdminMerchantRentOrderQueryRequest request) {
        SystemAdmin systemAdmin = SecurityUtil.getLoginUserVo().getUser();

        Page<Order> startPage = PageHelper.startPage(request.getPage(), request.getLimit());

        MPJLambdaWrapper<Order> lqw = new MPJLambdaWrapper<>();
        lqw.selectAll(Order.class);
        lqw.leftJoin(MerchantOrder.class, MerchantOrder::getPlatOrderNo, Order::getPlatOrderNo);
        lqw.leftJoin(OrderRentSharedRecord.class, OrderRentSharedRecord::getOrderNo, Order::getOrderNo);
//        lqw.select(Order::getOrderNo, Order::getUid, Order::getPayPrice, Order::getPayType, Order::getPaid, Order::getStatus, Order::getRefundStatus,
//                Order::getIsUserDel, Order::getCancelStatus, Order::getType, Order::getCreateTime, Order::getLevel, Order::getReceivingTime);
        lqw.eq(Order::getMerId, systemAdmin.getMerId());
        if (StrUtil.isNotBlank(request.getOrderNo())) {
            lqw.like(MerchantOrder::getOrderNo, URLUtil.decode(request.getOrderNo()));
        }
        // 单据类型不能为空
        request.setType(OrderType.RENT.code());
        if (ObjectUtil.isNotNull(request.getType())) {
            lqw.eq(Order::getType, request.getType());
        }
        if (Objects.nonNull(request.getOrderTimeStart()) && Objects.nonNull(request.getOrderTimeEnd())) {
            lqw.between(Order::getCreateTime, request.getOrderTimeStart(), request.getOrderTimeEnd());
        }
        if (Objects.nonNull(request.getExpireTimeStart()) && Objects.nonNull(request.getExpireTimeEnd())) {
            // todo eb_order_rent_shared_record   rent_end_date
            lqw.between(OrderRentSharedRecord::getRentEndDate, request.getExpireTimeStart(), request.getExpireTimeEnd());
        }
        // 订单状态
        if (CollectionUtils.isNotEmpty(request.getStatusList())) {
            lqw.in(Order::getStatus, request.getStatusList());
        }
        // 验货结果
//        if (Objects.nonNull(request.getVerifyResultCode())) {
//            lqw.eq(OrderRentSharedRecord::getVerifyResult, request.getVerifyResultCode());
//        }
        lqw.eq(Order::getIsMerchantDel, false);
        lqw.eq(Order::getLevel, OrderConstants.ORDER_LEVEL_MERCHANT);
        lqw.orderByDesc(Order::getId);
        List<Order> orderList = dao.selectJoinList(Order.class, lqw);
        if (CollUtil.isEmpty(orderList)) {
            return CommonPage.copyPageInfo(startPage, CollUtil.newArrayList());
        }
        List<Integer> uidList = orderList.stream().map(Order::getUid).distinct().collect(Collectors.toList());
        Map<Integer, User> userMap = userService.getUidMapList(uidList);

//        List<OrderStatus> orderStatuses = Lists.newArrayList();
//        List<String> orderNos = orderList.stream().filter(p -> p.getType() == OrderConstants.ORDER_TYPE_RENT.intValue()).map(Order::getOrderNo).distinct().collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(orderNos)) {
//            orderStatuses = orderStatusService.listDeliveryByOrder(orderNos);
//        }
//        List<OrderStatus> finalOrderStatuses = orderStatuses;

        Map<String, List<OrderDetail>> mapByOrderNoList = Maps.newHashMap();
        List<String> orderNos = orderList.stream().filter(p -> p.getType() == OrderConstants.ORDER_TYPE_RENT.intValue() && p.getReceivingTime() != null)
                .map(Order::getOrderNo).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(orderNos)) {
            mapByOrderNoList = orderDetailService.getMapByOrderNoList(orderNos);
        }

        Map<String, List<OrderDetail>> finalMapByOrderNoList = mapByOrderNoList;
        List<MerchantOrderPageNewResponse> pageResponses = orderList.stream().map(e -> {
            MerchantOrderPageNewResponse pageResponse = new MerchantOrderPageNewResponse();
            BeanUtils.copyProperties(e, pageResponse);
            MerchantOrder merchantOrder = merchantOrderService.getOneByPlatOrderNo(e.getPlatOrderNo());
            pageResponse.setShippingType(merchantOrder.getShippingType());
            pageResponse.setRemark(merchantOrder.getUserRemark());
//            pageResponse.setMerRemark(merchantOrder.getMerchantRemark());
            pageResponse.setNickName(userMap.get(e.getUid()).getNickname());

            // 计算订单到期时间
            if (e.getType() == OrderConstants.ORDER_TYPE_RENT.intValue() && e.getReceivingTime() != null) {
//                finalOrderStatuses.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getOrderNo(), pageResponse.getOrderNo()))
//                    .findFirst().ifPresent(c -> {
//                        pageResponse.setRentEndTime(c.getCreateTime());
//                    });

                List<OrderDetail> orderDetails = finalMapByOrderNoList.get(e.getOrderNo());
                if (CollectionUtils.isNotEmpty(orderDetails)) {
                    Integer rentDays = orderDetails.get(0).getRentDays();
                    Date endDate = DateUtils.addDays(e.getReceivingTime(), rentDays);
                    pageResponse.setRentEndTime(endDate);
                }
            }
            return pageResponse;
        }).collect(Collectors.toList());
        return CommonPage.copyPageInfo(startPage, pageResponses);
    }

    @Override
    public MerchantOrderDetailNewResponse getAdminMerchantOrderDetail(String orderNo) {
        SystemAdmin systemAdmin = SecurityUtil.getLoginUserVo().getUser();
        Order order = orderService.getByOrderNo(orderNo);
        if (order.getIsMerchantDel() || !order.getMerId().equals(systemAdmin.getMerId())) {
            throw new CrmebException("未找到对应订单信息");
        }
        // 订单信息
        MerchantOrderDetailNewResponse orderAdminDetailResponse = new MerchantOrderDetailNewResponse();
        Order merchantOrder = orderService.getOneByOrderNoAndType(orderNo, OrderType.RENT.getCode());
        BeanUtils.copyProperties(merchantOrder, orderAdminDetailResponse);
        BeanUtils.copyProperties(order, orderAdminDetailResponse);
        List<OrderDetail> orderDetailList = orderDetailService.getByOrderNo(orderNo);
        List<OrderInfoFrontDataResponse> orderInfoList = orderDetailList.stream().map(e -> {
            OrderInfoFrontDataResponse dataResponse = new OrderInfoFrontDataResponse();
            BeanUtils.copyProperties(e, dataResponse);
            return dataResponse;
        }).collect(Collectors.toList());
        orderAdminDetailResponse.setOrderDetailList(orderInfoList);

        // 用户信息
        User user = userService.getById(order.getUid());
        orderAdminDetailResponse.setRealName(user.getNickname());
        orderAdminDetailResponse.setUserPhone(user.getPhone());

        // ToDo 承享信息

        // 送货信息
        OrderInvoiceDTO expressInfo = orderInvoiceService.findOrderInvoiceByOrderNoAndInvoiceType(orderNo, ExpressOrderType.RENT_CREATE);
        if (Objects.nonNull(expressInfo)) {
            orderAdminDetailResponse.setShippingType(OrderConstants.ORDER_SHIPPING_TYPE_EXPRESS);
            orderAdminDetailResponse.setDeliveryName(expressInfo.getExpressName());
            orderAdminDetailResponse.setTrackingNumber(expressInfo.getTrackingNumber());
        }

        // 归还信息 eb_order_rent_shared_record
        OrderInvoiceDTO returnInfo = orderInvoiceService.findOrderInvoiceByOrderNoAndInvoiceType(orderNo, ExpressOrderType.RENT_RETURN);
        if (Objects.nonNull(returnInfo)) {
//           orderAdminDetailResponse.setPreReceiveTime();
//           orderAdminDetailResponse.setReturnTrack();
//           orderAdminDetailResponse.setActualReceiveTime();
//           orderAdminDetailResponse.setReturnStore("");
//           orderAdminDetailResponse.setReturnAmount();
        }

        // 验货信息

        // 支付信息
        return orderAdminDetailResponse;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmReceiptMerchantOrder(String orderNo) {
        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();

        // 确认收货
        LambdaUpdateWrapper<Order> updateWrapper = Wrappers.lambdaUpdate(Order.class);
        updateWrapper.set(Order::getStatus, OrderStatusEnums.RENT_PROGRESS.name());
        // update 条件
        updateWrapper.eq(Order::getOrderNo, orderNo);
        updateWrapper.eq(Order::getStatus, OrderStatusEnums.RENT_PROGRESS.name());
        updateWrapper.eq(Order::getUid, userInfo.getId());
        update(updateWrapper);

        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmDeliveryMerchantOrder(String orderNo, String deliveryCode) {
        // 验证提货码是否正确
        MerchantOrderAppointment appointment = merchantOrderAppointmentService.findAppointmentByOrderId(orderNo, MerOrderApptType.RENT_CREATE);
        if (Objects.isNull(appointment) || !appointment.getApptNumber().equals(deliveryCode)) {
            throw new CrmebException("提货码错误");
        }

        // 获取用户信息
        UserInfoResponse userInfo = userService.getUserInfo();

        // 确认提货
        LambdaUpdateWrapper<Order> updateWrapper = Wrappers.lambdaUpdate(Order.class);
        updateWrapper.set(Order::getStatus, OrderStatusEnums.RENT_COMPLETE.name());
        // update 条件
        updateWrapper.eq(Order::getOrderNo, orderNo);
        updateWrapper.eq(Order::getStatus, OrderStatusEnums.RENT_COMPLETE.name());
        updateWrapper.eq(Order::getUid, userInfo.getId());
        update(updateWrapper);

        return Boolean.TRUE;
    }

    @Override
    public Boolean deliveryMerchantOrder(OrderSendRequest request) {
        return orderService.send(request);
    }

    @Override
    public List<LogisticsResultVo> getLogisticsMerchantOrder(String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            throw new CrmebException("单号不能为空");
        }
        // todo 需确认调用 order_invoice 获取express_no 再调logisticService.info  还是直接从logisticService方法中获取
        return orderInvoiceService.findTraceByOrderNoAndLastTraceOnly(orderNo);
    }

    @Override
    public Boolean checkMerchantOrder(AdminMerchantRentOrderVerifyRequest request) {
        // 验货结果【通过】，则订单状态更新为【已完成】，若验货结果【不通过】，则订单状态更新为【无法回收】
        Order order = orderService.getByOrderNo(request.getOrderNo());
        if (Objects.isNull(order)) {
            throw new CrmebException("订单不存在");
        }
        if (order.getStatus().equals(OrderStatusEnums.RENT_WAIT_RECEIPT.getCode())) {
            // 订单状态【用户待收货】，验货结果【通过】，则订单状态更新为【已完成】，若验货结果【不通过】，则订单状态更新为【无法回收】
            if (request.getVerifyResultCode()) {
                order.setStatus(OrderStatusEnums.RENT_COMPLETE.getCode());
            } else {
                order.setStatus(OrderStatusEnums.RENT_UNRECOVERABLE.getCode());
            }
            order.setUpdateTime(new Date());
            updateById(order);
        }

        return Boolean.TRUE;
    }

    @Override
    public Boolean urgeMerchantOrder(String orderNo) {
        // todo
        // 对用户下发对应的催收短信，短信文案详见文档，短信下发至收货人手机号上
        Order order = orderService.getByOrderNo(orderNo);
        if (Objects.isNull(order)) {
            throw new CrmebException("订单不存在");
        }
        // eb_order_address
        List<OrderAddress> orderAddress = orderAddressService.getOrderAddressList(order.getOrderNo(), ExpressOrderType.RENT_CREATE.name());
        if (CollectionUtils.isEmpty(orderAddress)) {
            throw new CrmebException("订单收货地址不存在");
        }
        // 获取收货人手机号
        String contactPhone = orderAddress.get(0).getContactPhone();
        // 获取商品名称
        OrderDetail orderDetail = orderDetailService.getOneByOrderNo(orderNo);

        // 获取催收文案 亲爱的【白银蟹主】，您承享的奢品【商品名称XXX】承享服务已到期，请尽快归还，感谢您的理解与配合~
        // todo 需配置模板
        // 调用短信发送接口
        smsService.sendUrgeNotice(contactPhone, order.getMerId().toString(), orderDetail.getProductName());
        return Boolean.TRUE;
    }
}
